/*
 * Copyright (C) RT, 2017 by gf.wu
 */

package com.zgys.mes.util.deadlock;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


public class DeadLockDetector {
        private final List<DeadLockHandler> deadLockHandlers = new LinkedList<>();
        private final ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
        private final long period;
        private final TimeUnit unit;
        private final ScheduledExecutorService schedule = Executors.newScheduledThreadPool(1);


        private final Runnable deadlockCheck = new Runnable() {
            @Override
            public void run() {
                long[] deadLockThreadIds = mbean.findMonitorDeadlockedThreads();
                if (deadLockThreadIds != null) {
                    ThreadInfo[] threadInfos = mbean.getThreadInfo(deadLockThreadIds);

                    deadLockHandlers.forEach(handler -> handler.handle(threadInfos));
                }
            }
        };


        public DeadLockDetector( final long period, final TimeUnit unit) {
            this.period = period;
            this.unit = unit;
            DeadLockConsoleHandler deadLockHandler = new DeadLockConsoleHandler();
            deadLockHandlers.add(deadLockHandler);
        }


        public void addHandler(final DeadLockHandler handle) {
            deadLockHandlers.add(handle);
        }


        public void  start() {
            schedule.scheduleAtFixedRate(deadlockCheck, period, period, unit);
        }
}

